home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * fopenRF.c -- Clone of fopen.c to open Mac resource forks.
- *
- * Copyright (c) 1989 Symantec Corporation. All rights reserved.
- *
- */
-
- #include "stdio.h"
- #include "errno.h"
- #include "string.h"
- #include "ansi_private.h"
-
- FILE *fopenRF(char *, char *);
- FILE *freopenRF(char *, char *, FILE *);
- FILE *__openRF(char *, int, int, FILE *);
-
- #include <Files.h>
-
- #define fcbVPtr(fcb) (* (VCB **) (fcb + 20))
- #define fcbDirID(fcb) (* (long *) (fcb + 58))
- #define fcbCName(fcb) (fcb + 62)
-
- static void setfiletype(StringPtr, int);
- static void stdio_exit(void);
- static int fileio(FILE *, int);
- static int close(FILE *);
- static void replace(unsigned char *, size_t, int, int);
-
-
- FILE *
- fopenRF(filename, mode)
- char *filename, *mode;
- {
- return(freopenRF(filename, mode, __getfile()));
- }
-
-
- FILE *
- freopenRF(filename, mode, fp)
- char *filename;
- register char *mode;
- register FILE *fp;
- {
- int omode, oflag;
-
- /* interpret "rwa" */
-
- if (mode[0] == 'r') {
- omode = fsRdPerm;
- oflag = 0;
- }
- else if (mode[0] == 'w') {
- omode = fsWrPerm;
- oflag = F_CREAT+F_TRUNC;
- }
- else if (mode[0] == 'a') {
- omode = fsWrPerm;
- oflag = F_CREAT+F_APPEND;
- }
- else {
- errno = EINVAL;
- return(NULL);
- }
-
- /* interpret "b+" */
-
- if (mode[1] == 'b') {
- oflag |= F_BINARY;
- if (mode[2] == '+')
- omode = fsRdWrPerm;
- }
- else if (mode[1] == '+') {
- omode = fsRdWrPerm;
- if (mode[2] == 'b')
- oflag |= F_BINARY;
- }
-
- /* open the file */
-
- return(__openRF(filename, omode, oflag, fp));
- }
-
-
- FILE *
- __openRF(filename, omode, oflag, fp)
- char *filename;
- int omode, oflag;
- register FILE *fp;
- {
- ioParam pb;
- char pname[FILENAME_MAX];
-
- if (fp == NULL)
- return(NULL);
- fclose(fp);
-
- /* set up pb */
-
- pb.ioNamePtr = __c2p(filename, pname);
- pb.ioVRefNum = 0;
- pb.ioVersNum = 0;
- pb.ioPermssn = omode;
- pb.ioMisc = 0;
-
- /* create file */
-
- if (oflag & F_CREAT) {
- asm {
- lea pb,a0
- _PBCreate
- }
- if (pb.ioResult == noErr)
- oflag &= ~F_TRUNC;
- else if (pb.ioResult == dupFNErr && !(oflag & F_EXCL))
- oflag &= ~F_CREAT;
- else {
- errno = pb.ioResult;
- return(NULL);
- }
- }
-
- /* open resource file */
-
- asm {
- lea pb,a0
- _PBOpenRF
- }
- if (pb.ioResult) {
- errno = pb.ioResult;
- if (oflag & F_CREAT) asm {
- lea pb,a0
- _PBDelete
- }
- return(NULL);
- }
- fp->refnum = pb.ioRefNum;
-
- /* get/set file length */
-
- if (oflag & F_TRUNC) asm {
- lea pb,a0
- _PBSetEOF
- }
- else if (!(oflag & F_CREAT)) asm {
- lea pb,a0
- _PBGetEOF
- }
- fp->len = (fpos_t) pb.ioMisc;
-
- /* initialize rest of FILE structure */
-
- if (oflag & F_APPEND) {
- fp->append = 1;
- fp->pos = fp->len;
- }
- if (oflag & F_BINARY)
- fp->binary = 1;
- setvbuf(fp, NULL, _IOFBF, BUFSIZ);
- fp->proc = fileio;
-
- /* set file type */
-
- if (oflag & (F_CREAT|F_TRUNC))
- setfiletype(pb.ioNamePtr, oflag);
-
- /* done */
-
- __atexit_stdio(stdio_exit);
- return(fp);
- }
-
-
- /*
- * setfiletype - set type/creator of new file
- *
- */
-
- static void
- setfiletype(name, oflag)
- StringPtr name;
- int oflag;
- {
- fileParam pb;
-
- pb.ioNamePtr = name;
- pb.ioVRefNum = 0;
- pb.ioFVersNum = 0;
- pb.ioFDirIndex = 0;
- asm {
- lea pb,a0
- _PBGetFInfo
- bmi.s @1
- }
- pb.ioFlFndrInfo.fdType = pb.ioFlFndrInfo.fdCreator = '????';
- if (!(oflag & F_BINARY))
- pb.ioFlFndrInfo.fdType = 'TEXT';
- asm {
- lea pb,a0
- _PBSetFInfo
- @1 }
- }
-
-
- /*
- * stdio_exit - stdio shutdown routine
- *
- */
-
- static void
- stdio_exit()
- {
- register FILE *fp;
- int n;
-
- for (fp = &__file[0], n = FOPEN_MAX; n--; fp++)
- fclose(fp);
- }
-
-
- /*
- * fileio - I/O handler proc for files and devices
- *
- */
-
- static int
- fileio(fp, i)
- register FILE *fp;
- int i;
- {
- ioParam pb;
-
- pb.ioRefNum = fp->refnum;
- switch (i) {
-
- /* read */
-
- case 0:
- pb.ioBuffer = (Ptr) fp->ptr;
- pb.ioReqCount = fp->cnt;
- pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
- pb.ioPosOffset = fp->pos - fp->cnt;
- asm {
- lea pb,a0
- _PBRead
- }
- if (pb.ioResult == eofErr) {
- fp->pos = pb.ioPosOffset;
- if (fp->cnt = pb.ioActCount)
- pb.ioResult = 0;
- else {
- fp->eof = 1;
- return(EOF);
- }
- }
- if (pb.ioResult) {
- fp->pos -= fp->cnt;
- fp->cnt = 0;
- }
- else if (!fp->binary)
- replace(fp->ptr, fp->cnt, '\r', '\n');
- break;
-
- /* write */
-
- case 1:
- pb.ioBuffer = (Ptr) fp->ptr;
- pb.ioReqCount = fp->cnt;
- pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
- if ((pb.ioPosOffset = fp->pos - fp->cnt) > fp->len) {
- pb.ioMisc = (Ptr) pb.ioPosOffset;
- asm {
- lea pb,a0
- _PBSetEOF
- bmi.s @1
- }
- }
- if (!fp->binary)
- replace(fp->ptr, fp->cnt, '\n', '\r');
- asm {
- lea pb,a0
- _PBWrite
- @1 }
- if (pb.ioResult) {
- fp->pos -= fp->cnt;
- fp->cnt = 0;
- }
- else if (pb.ioPosOffset > fp->len)
- fp->len = pb.ioPosOffset;
- break;
-
- /* close */
-
- case 2:
- pb.ioResult = close(fp);
- break;
- }
-
- /* done */
-
- if (pb.ioResult) {
- fp->err = 1;
- errno = pb.ioResult;
- return(EOF);
- }
- return(0);
- }
-
-
- static int
- close(fp)
- register FILE *fp;
- {
- HFileParam pb;
- Str255 buf;
- register char *fcb = FCBSPtr + fp->refnum;
- VCB *vcb = fcbVPtr(fcb);
- register char *s;
-
- pb.ioNamePtr = buf;
- pb.ioFRefNum = fp->refnum;
- pb.ioVRefNum = vcb->vcbVRefNum;
- pb.ioFVersNum = 0;
-
- /* close temporary file - HFS */
-
- if (fp->delete && vcb->vcbSigWord == 0x4244) {
- pb.ioDirID = fcbDirID(fcb);
- s = fcbCName(fcb);
- asm {
- lea buf,a0
- moveq #0,d0
- move.b (s),d0
- @1 move.b (s)+,(a0)+
- dbra d0,@1
- lea pb,a0
- _PBClose
- bmi.s @9
- _PBHDelete
- }
- }
-
- /* close temporary file - MFS */
-
- else if (fp->delete && vcb->vcbSigWord == 0xD2D7) {
- pb.ioFDirIndex = 1;
- do asm {
- lea pb,a0
- _PBGetFInfo
- bmi.s @2
- addq.w #1,pb.ioFDirIndex
- } while (pb.ioFRefNum != fp->refnum);
- asm {
- lea pb,a0
- _PBClose
- bmi.s @9
- _PBDelete
- }
- }
-
- /* normal case - just close file */
-
- else {
- asm {
- @2 lea pb,a0
- _PBClose
- bmi.s @9
- }
- }
-
- /* flush volume buffer */
-
- pb.ioNamePtr = 0;
- asm {
- lea pb,a0
- _PBFlshVol
- @9 }
- return(pb.ioResult);
- }
-
-
- /*
- * replace - routine for doing CR/LF conversion
- *
- */
-
- static void
- replace(s, n, c1, c2)
- register unsigned char *s;
- register size_t n;
- register int c1, c2;
- {
- register unsigned char *t;
-
- for (; n && (t = memchr(s, c1, n)); s = t) {
- *t++ = c2;
- n -= t - s;
- }
- }
-